<template>
  <div class="role-list-container">
    <el-card class="page-header">
      <h2>角色管理</h2>
      <p>管理系统中的角色权限配置</p>
    </el-card>
    
    <el-card class="search-section">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="角色名称">
          <el-input v-model="searchForm.roleName" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item label="角色代码">
          <el-input v-model="searchForm.roleCode" placeholder="请输入角色代码"></el-input>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态">
            <el-option label="全部" value=""></el-option>
            <el-option label="启用" value="1"></el-option>
            <el-option label="禁用" value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="searchRoles">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <el-button type="success" @click="handleCreateRole">新增角色</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    
    <el-card class="data-table">
      <el-table :data="roleList" border style="width: 100%">
        <el-table-column prop="id" label="角色ID" width="80" align="center"></el-table-column>
        <el-table-column prop="roleName" label="角色名称" min-width="120"></el-table-column>
        <el-table-column prop="roleCode" label="角色代码" min-width="120"></el-table-column>
        <el-table-column prop="description" label="角色描述" min-width="200"></el-table-column>
        <el-table-column prop="status" label="状态" width="80" align="center">
          <template #default="scope">
            <el-switch 
              v-model="scope.row.status" 
              active-value="1" 
              inactive-value="0" 
              @change="handleStatusChange(scope.row)"
              :disabled="scope.row.roleCode === 'ADMIN'"
            ></el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" min-width="160"></el-table-column>
        <el-table-column label="操作" width="240" fixed="right" align="center">
          <template #default="scope">
            <el-button type="primary" size="small" @click="handleEditRole(scope.row)">编辑</el-button>
            <el-button type="success" size="small" @click="handleAssignMenus(scope.row)">分配菜单</el-button>
            <el-button type="danger" size="small" @click="handleDeleteRole(scope.row)" :disabled="scope.row.roleCode === 'ADMIN'">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.currentPage"
          v-model:page-size="pagination.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="pagination.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        ></el-pagination>
      </div>
    </el-card>
    
    <!-- 角色编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px" :close-on-click-modal="false">
      <el-form ref="roleFormRef" :model="formData" :rules="formRules" label-width="80px">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="formData.roleName" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item label="角色代码" prop="roleCode" :disabled="!!formData.id">
          <el-input v-model="formData.roleCode" placeholder="请输入角色代码（大写字母和下划线）"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="formData.description" type="textarea" placeholder="请输入角色描述" :rows="3"></el-input>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-switch v-model="formData.status" active-value="1" inactive-value="0"></el-switch>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </span>
      </template>
    </el-dialog>
    
    <!-- 菜单分配对话框 -->
    <el-dialog v-model="menuDialogVisible" title="分配菜单权限" width="600px" :close-on-click-modal="false">
      <div class="menu-tree-container">
        <el-tree 
          ref="menuTreeRef"
          :data="menuTreeData" 
          show-checkbox 
          node-key="id" 
          :props="defaultProps" 
          :check-strictly="false"
          @check-change="handleMenuCheckChange"
        ></el-tree>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="menuDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitMenuAssignment">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted } from 'vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'

// 导入角色相关API
import { 
  getRoleList, 
  createRole, 
  updateRole, 
  deleteRole, 
  updateRoleStatus,
  getRoleMenus, 
  assignRoleMenus,
  getMenuTree 
} from '../../api/role.js'

export default {
  name: 'RoleList',
  setup() {
    // 搜索表单
    const searchForm = reactive({
      roleName: '',
      roleCode: '',
      status: ''
    })
    
    // 角色列表数据
    const roleList = ref([])
    
    // 分页数据
    const pagination = reactive({
      currentPage: 1,
      pageSize: 10,
      total: 0
    })
    
    // 对话框状态
    const dialogVisible = ref(false)
    const dialogTitle = ref('新增角色')
    const menuDialogVisible = ref(false)
    
    // 表单数据
    const formData = reactive({
      id: '',
      roleName: '',
      roleCode: '',
      description: '',
      status: '1'
    })
    
    // 表单验证规则
    const formRules = {
      roleName: [
        { required: true, message: '请输入角色名称', trigger: 'blur' },
        { min: 2, max: 20, message: '角色名称长度在 2 到 20 个字符', trigger: 'blur' }
      ],
      roleCode: [
        { required: true, message: '请输入角色代码', trigger: 'blur' },
        { pattern: /^[A-Z_]+$/, message: '角色代码只能包含大写字母和下划线', trigger: 'blur' },
        { min: 3, max: 30, message: '角色代码长度在 3 到 30 个字符', trigger: 'blur' }
      ],
      description: [
        { max: 255, message: '角色描述不能超过255个字符', trigger: 'blur' }
      ],
      status: [
        { required: true, message: '请选择状态', trigger: 'change' }
      ]
    }
    
    // 表单引用
    const roleFormRef = ref(null)
    const menuTreeRef = ref(null)
    
    // 菜单树数据
    const menuTreeData = ref([])
    const defaultProps = {
      children: 'children',
      label: 'menuName'
    }
    
    // 当前正在分配菜单的角色ID
    const currentRoleId = ref('')
    
    // 加载角色列表
    const loadRoleList = async () => {
      try {
        const params = {
          pageNum: pagination.currentPage,
          pageSize: pagination.pageSize,
          roleName: searchForm.roleName,
          roleCode: searchForm.roleCode,
          status: searchForm.status
        }
        const response = await getRoleList(params)
        if (response.code === 200) {
          roleList.value = response.data.list
          pagination.total = response.data.total
        } else {
          ElMessage.error(response.message || '获取角色列表失败')
        }
      } catch (error) {
        console.error('获取角色列表失败:', error)
        ElMessage.error('获取角色列表失败')
      }
    }
    
    // 搜索角色
    const searchRoles = () => {
      pagination.currentPage = 1
      loadRoleList()
    }
    
    // 重置搜索条件
    const resetSearch = () => {
      searchForm.roleName = ''
      searchForm.roleCode = ''
      searchForm.status = ''
      pagination.currentPage = 1
      loadRoleList()
    }
    
    // 切换分页大小
    const handleSizeChange = (size) => {
      pagination.pageSize = size
      loadRoleList()
    }
    
    // 切换当前页
    const handleCurrentChange = (current) => {
      pagination.currentPage = current
      loadRoleList()
    }
    
    // 打开新增角色对话框
    const handleCreateRole = () => {
      dialogTitle.value = '新增角色'
      // 重置表单数据
      Object.keys(formData).forEach(key => {
        formData[key] = key === 'status' ? '1' : ''
      })
      dialogVisible.value = true
    }
    
    // 打开编辑角色对话框
    const handleEditRole = (role) => {
      dialogTitle.value = '编辑角色'
      // 复制角色数据到表单
      Object.assign(formData, {
        id: role.id,
        roleName: role.roleName,
        roleCode: role.roleCode,
        description: role.description,
        status: role.status.toString()
      })
      dialogVisible.value = true
    }
    
    // 提交表单
    const submitForm = async () => {
      if (!roleFormRef.value) return
      
      try {
        await roleFormRef.value.validate()
        
        const data = {
          ...formData,
          status: Number(formData.status)
        }
        
        let response
        if (formData.id) {
          // 更新角色
          response = await updateRole(data)
        } else {
          // 创建角色
          response = await createRole(data)
        }
        
        if (response.code === 200) {
          ElMessage.success(formData.id ? '更新角色成功' : '创建角色成功')
          dialogVisible.value = false
          loadRoleList()
        } else {
          ElMessage.error(response.message || (formData.id ? '更新角色失败' : '创建角色失败'))
        }
      } catch (error) {
        console.error(formData.id ? '更新角色失败:' : '创建角色失败:', error)
        if (error?.message) {
          ElMessage.error(error.message)
        } else {
          ElMessage.error(formData.id ? '更新角色失败' : '创建角色失败')
        }
      }
    }
    
    // 删除角色
    const handleDeleteRole = (role) => {
      if (role.roleCode === 'ADMIN') {
        ElMessage.warning('不能删除管理员角色')
        return
      }
      
      ElMessageBox.confirm(`确定要删除角色 ${role.roleName} 吗？`, '删除角色', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const response = await deleteRole(role.id)
          if (response.code === 200) {
            ElMessage.success('删除角色成功')
            loadRoleList()
          } else {
            ElMessage.error(response.message || '删除角色失败')
          }
        } catch (error) {
          console.error('删除角色失败:', error)
          ElMessage.error('删除角色失败')
        }
      }).catch(() => {
        // 用户取消删除
      })
    }
    
    // 切换角色状态
    const handleStatusChange = async (role) => {
      try {
        const response = await updateRoleStatus(role.id, role.status)
        if (response.code === 200) {
          ElMessage.success(role.status === '1' ? '启用角色成功' : '禁用角色成功')
        } else {
          // 恢复原来的状态
          role.status = role.status === '1' ? '0' : '1'
          ElMessage.error(response.message || (role.status === '1' ? '启用角色失败' : '禁用角色失败'))
        }
      } catch (error) {
        // 恢复原来的状态
        role.status = role.status === '1' ? '0' : '1'
        console.error('更新角色状态失败:', error)
        ElMessage.error('更新角色状态失败')
      }
    }
    
    // 加载菜单树
    const loadMenuTree = async () => {
      try {
        const response = await getMenuTree()
        if (response.code === 200) {
          menuTreeData.value = response.data
        } else {
          ElMessage.error(response.message || '获取菜单树失败')
        }
      } catch (error) {
        console.error('获取菜单树失败:', error)
        ElMessage.error('获取菜单树失败')
      }
    }
    
    // 打开分配菜单对话框
    const handleAssignMenus = async (role) => {
      currentRoleId.value = role.id
      menuDialogVisible.value = true
      
      // 加载菜单树
      await loadMenuTree()
      
      // 加载角色已分配的菜单
      try {
        const response = await getRoleMenus(role.id)
        if (response.code === 200) {
          const menuIds = response.data
          // 延迟设置选中状态，确保菜单树已渲染
          setTimeout(() => {
            if (menuTreeRef.value) {
              menuTreeRef.value.setCheckedKeys(menuIds)
            }
          }, 100)
        } else {
          ElMessage.error(response.message || '获取角色菜单失败')
        }
      } catch (error) {
        console.error('获取角色菜单失败:', error)
        ElMessage.error('获取角色菜单失败')
      }
    }
    
    // 提交菜单分配
    const submitMenuAssignment = async () => {
      if (!menuTreeRef.value) return
      
      const checkedKeys = menuTreeRef.value.getCheckedKeys()
      
      try {
        const response = await assignRoleMenus(currentRoleId.value, checkedKeys)
        if (response.code === 200) {
          ElMessage.success('菜单分配成功')
          menuDialogVisible.value = false
        } else {
          ElMessage.error(response.message || '菜单分配失败')
        }
      } catch (error) {
        console.error('菜单分配失败:', error)
        ElMessage.error('菜单分配失败')
      }
    }
    
    // 菜单勾选变化处理
    const handleMenuCheckChange = (data, checked, indeterminate) => {
      // 可以在这里添加额外的勾选逻辑
    }
    
    // 初始化加载
    onMounted(() => {
      loadRoleList()
    })
    
    return {
      searchForm,
      roleList,
      pagination,
      dialogVisible,
      dialogTitle,
      menuDialogVisible,
      formData,
      formRules,
      roleFormRef,
      menuTreeRef,
      menuTreeData,
      defaultProps,
      searchRoles,
      resetSearch,
      handleSizeChange,
      handleCurrentChange,
      handleCreateRole,
      handleEditRole,
      submitForm,
      handleDeleteRole,
      handleStatusChange,
      handleAssignMenus,
      submitMenuAssignment,
      handleMenuCheckChange
    }
  }
}
</script>

<style scoped>
.role-list-container {
  padding: 20px;
}

.page-header {
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0 0 10px 0;
  font-size: 20px;
  font-weight: 600;
}

.page-header p {
  margin: 0;
  color: #606266;
}

.search-section {
  margin-bottom: 20px;
  padding: 15px 0;
}

.data-table {
  margin-bottom: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.menu-tree-container {
  max-height: 400px;
  overflow-y: auto;
  padding: 10px 0;
}

.menu-tree-container .el-tree {
  font-size: 14px;
}

.el-table .cell {
  white-space: nowrap;
}

.el-table th {
  background-color: #f5f7fa !important;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>